using System;
using System.ComponentModel;
using System.IO;
using System.Windows.Forms;
using Habanero.BO;
using Habanero.UI.Base;
using Habanero.UI.Win;
using Habanero.Base;
using log4net;
using UseCaseManager.BO;
using UseCaseManager.Menu;
using UseCaseManager.UI.Menu;
using DialogResult = Habanero.UI.Base.DialogResult;
using MessageBoxButtons = Habanero.UI.Base.MessageBoxButtons;
using MessageBoxIcon = Habanero.UI.Base.MessageBoxIcon;

namespace UseCaseManager
{
    static class Program
    {
        private static readonly ILog log = LogManager.GetLogger(typeof(Program));
        private static DataStoreInMemory _loadedDataStore;
        private static string _dataFileLocation;

        [STAThread]
        static void Main()
        {
            GlobalRegistry.ApplicationName = "UseCaseManager";
            GlobalRegistry.ApplicationVersion = "v1.0";
            HabaneroAppMemoryWin mainApp = new HabaneroAppMemoryWin(GlobalRegistry.ApplicationName, GlobalRegistry.ApplicationVersion) { ClassDefsXml = BOBroker.GetClassDefsXml() };
            try
            {
                log.Debug(string.Format("-------- {0} {1} Starting  ---------", GlobalRegistry.ApplicationName, GlobalRegistry.ApplicationVersion));
                if (!mainApp.Startup()) return;
            }
            catch (Exception ex)
            {
                log.Error(ex.Message);
            }

            try
            {
                //TODO: default save to xml
                //TODO: provide open, save as dialogs
                //Binary Serialization- default save method
                //Customised so as to save the state of all the business objects to an appropriate file.
                _dataFileLocation = Path.Combine(Application.StartupPath + @"\SerialiseData", "Project.dat");
                _loadedDataStore = new DataStoreInMemory();
                BORegistry.DataAccessor = new DataAccessorInMemory(_loadedDataStore);
                if (File.Exists(_dataFileLocation))
                {
                    _loadedDataStore.Load(_dataFileLocation);
                }
                BORegistry.DataAccessor = new DataAccessorInMemory(_loadedDataStore);

                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);

                FormWin programForm = new FormWin();
                SetupMainForm(programForm);
                Application.Run(programForm);
            }
            catch (Exception ex)
            {
                GlobalRegistry.UIExceptionNotifier.Notify(ex,
                        "An error has occurred in the application.",
                        "Application Error");
            }
        }

        public static void SetupMainForm(IFormHabanero programForm)
        {
            IControlFactory factory = new ControlFactoryWin();
            IMainMenuHabanero mainMenuHabanero = SetupMainMenu(programForm, factory, new MenuBuilderWin(factory));
            mainMenuHabanero.DockInForm(programForm);
            programForm.Text = GlobalRegistry.ApplicationName + " " + GlobalRegistry.ApplicationVersion;
            programForm.WindowState = Habanero.UI.Base.FormWindowState.Maximized;
            Form programFormWin = (Form)programForm;
            programFormWin.Closing += ProgramFormWin_OnClosing;
        }

        private static void ProgramFormWin_OnClosing(object sender, CancelEventArgs e)
        {
            DialogResult confirm = GlobalUIRegistry.ControlFactory.ShowMessageBox("Do you want to save changes?", "Use Case Manager", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
            if (confirm == DialogResult.Yes)
            {
                SaveCurrentDataStore();
            }
            else if (confirm == DialogResult.Cancel)
            {
                e.Cancel = true;
            }
        }

        public static IMainMenuHabanero SetupMainMenu(IFormHabanero programForm, IControlFactory controlFactory, IMenuBuilder menuBuilder)
        {
            HabaneroMenu mainMenu = new HabaneroMenu("Main", programForm, GlobalUIRegistry.ControlFactory);
            HabaneroMenu currentMenu = mainMenu.AddSubMenu("&File");
            //Customised so as to save the state of all the business objects to an appropriate file.
            HabaneroMenu.Item saveMenuHandler = currentMenu.AddMenuItem("&Save");
            saveMenuHandler.CustomHandler += ((sender1, e1) => SaveCurrentDataStore());
            HabaneroMenu.Item currentMenuItem = currentMenu.AddMenuItem("E&xit");
            currentMenuItem.CustomHandler += ((sender, e) => programForm.Close());

            AddManageMenu(mainMenu, controlFactory);
            //AddGeneratedFormsMenu(mainMenu, controlFactory);

            return menuBuilder.BuildMainMenu(mainMenu);
        }

        private static void AddManageMenu(HabaneroMenu mainMenu, IControlFactory controlFactory)
        {
            //TODO: Review menu structure
            HabaneroMenu manageMenu = mainMenu.AddSubMenu("&Manage Use Cases");
            MenuItemCreator menuItemCreator;

            menuItemCreator = new ProjectsGridControlMenuItem();
            menuItemCreator.AddToMenu(manageMenu, controlFactory);

            menuItemCreator = new PackagesAndUseCasesControlMenuItem();
            menuItemCreator.AddToMenu(manageMenu, controlFactory);

            menuItemCreator = new UseCasesAndUseCaseStepsControlMenuItem();
            menuItemCreator.AddToMenu(manageMenu, controlFactory);

            menuItemCreator = new ReleasesAndDropsControlMenuItem();
            menuItemCreator.AddToMenu(manageMenu, controlFactory);

            menuItemCreator = new ReleaseDropsPlanningControlMenuItem();
            menuItemCreator.AddToMenu(manageMenu, controlFactory);

            menuItemCreator = new DropCompletionControlMenuItem();
            menuItemCreator.AddToMenu(manageMenu, controlFactory);

            menuItemCreator = new BurnDownChartControlMenuItem();
            menuItemCreator.AddToMenu(manageMenu, controlFactory);
        }


        //private static void AddGeneratedFormsMenu(HabaneroMenu menu, IControlFactory controlFactory)
        //{
        //    HabaneroMenu dataMenu = menu.AddSubmenu("&Generated Forms");
        //    foreach (Type type in typeof(Program).Assembly.GetTypes())
        //    {
        //        if (!type.IsSubclassOf(typeof(MenuItemCreator))) continue;
        //        MenuItemCreator menuItemCreator = (MenuItemCreator)Activator.CreateInstance(type, new object[] { });
        //        menuItemCreator.AddToMenu(dataMenu, controlFactory);
        //    }
        //}

        private static void SaveCurrentDataStore()
        {
            //Customised so as to save the state of all the business objects to an appropriate file.
            _loadedDataStore.Save(_dataFileLocation);
        }
    }
}